home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / adainc / s-exngen.adb < prev    next >
Text File  |  1996-01-30  |  5KB  |  133 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --                       S Y S T E M . E X N _ G E N                        --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.5 $                              --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. package body System.Exn_Gen is
  27.  
  28.    --------------------
  29.    -- Exn_Float_Type --
  30.    --------------------
  31.  
  32.    function Exn_Float_Type
  33.      (Left : Type_Of_Base; Right : Integer) return Type_Of_Base
  34.    is
  35.       pragma Suppress (Division_Check);
  36.       pragma Suppress (Overflow_Check);
  37.  
  38.       Result : Type_Of_Base := 1.0;
  39.       Factor : Type_Of_Base := Left;
  40.       Exp    : Integer := Right;
  41.  
  42.    begin
  43.       --  We use the standard logarithmic approach, Exp gets shifted right
  44.       --  testing successive low order bits and Factor is the value of the
  45.       --  base raised to the next power of 2. For positive exponents we
  46.       --  multiply the result by this factor, for negative exponents, we
  47.       --  Division by this factor.
  48.  
  49.       if Exp >= 0 then
  50.  
  51.          --  For a positive exponent, if we get a constraint error during
  52.          --  this loop, it is an overflow, and the constraint error will
  53.          --  simply be passed on to the caller.
  54.  
  55.          while Exp /= 0 loop
  56.             if Exp rem 2 /= 0 then
  57.                Result := Result * Factor;
  58.             end if;
  59.  
  60.             Factor := Factor * Factor;
  61.             Exp := Exp / 2;
  62.          end loop;
  63.  
  64.          return Result;
  65.  
  66.       else -- Exp < 0 then
  67.  
  68.          --  For the negative exponent case, a constraint error during this
  69.          --  calculation happens if Factor gets too large, and the proper
  70.          --  response is to return 0.0, since what we essenmtially have is
  71.          --  1.0 / infinity, and the closest model number will be zero.
  72.  
  73.          begin
  74.  
  75.             while Exp /= 0 loop
  76.                if Exp rem 2 /= 0 then
  77.                   Result := Result * Factor;
  78.                end if;
  79.  
  80.                Factor := Factor * Factor;
  81.                Exp := Exp / 2;
  82.             end loop;
  83.  
  84.             return 1.0 / Result;
  85.  
  86.          exception
  87.  
  88.             when Constraint_Error =>
  89.                return 0.0;
  90.          end;
  91.       end if;
  92.    end Exn_Float_Type;
  93.  
  94.    ----------------------
  95.    -- Exn_Integer_Type --
  96.    ----------------------
  97.  
  98.    --  Note that negative exponents get a constraint error because the
  99.    --  subtype of the Right argument (the exponent) is Natural.
  100.  
  101.    function Exn_Integer_Type
  102.      (Left : Type_Of_Base; Right : Natural) return Type_Of_Base
  103.    is
  104.       pragma Suppress (Division_Check);
  105.       pragma Suppress (Overflow_Check);
  106.  
  107.       Result : Type_Of_Base := 1;
  108.       Factor : Type_Of_Base := Left;
  109.       Exp    : Natural := Right;
  110.  
  111.    begin
  112.       --  We use the standard logarithmic approach, Exp gets shifted right
  113.       --  testing successive low order bits and Factor is the value of the
  114.       --  base raised to the next power of 2.
  115.  
  116.       --  Note: it is not worth special casing the cases of base values -1,0,+1
  117.       --  since the expander does this when the base is a literal, and other
  118.       --  cases will be extremely rare.
  119.  
  120.       while Exp /= 0 loop
  121.          if Exp rem 2 /= 0 then
  122.             Result := Result * Factor;
  123.          end if;
  124.  
  125.          Factor := Factor * Factor;
  126.          Exp := Exp / 2;
  127.       end loop;
  128.  
  129.       return Result;
  130.    end Exn_Integer_Type;
  131.  
  132. end System.Exn_Gen;
  133.